package com.linkgie.galaxyframework.web.client;

import com.linkgie.galaxyframework.httpproxy.ResponseHandler;
import com.linkgie.galaxyframework.httpproxy.ServiceInvocationContext;
import com.linkgie.galaxyframework.httpproxy.ServiceRequest;
import com.linkgie.galaxyframework.httpproxy.converters.JsonResponseHandler;
import com.linkgie.galaxyframework.utils.json.JsonElement;
import com.linkgie.galaxyframework.utils.lang.DataTypeUtils;
import com.linkgie.galaxyframework.web.ServiceResponse;

public class ServiceResponseHandler implements ResponseHandler {

	private JsonResponseHandler jsonConverter = new JsonResponseHandler(ServiceResponse.class);

	private Class<?> dataClazz;

	public ServiceResponseHandler(Class<?> dataClazz) {
		this.dataClazz = dataClazz;
	}

	@Override
	public Object handleResponse(ServiceRequest request,
			com.linkgie.galaxyframework.httpproxy.ServiceResponse response, ServiceInvocationContext serviceContext)
			throws Exception {
		ServiceResponse<?> webServerResponse = (ServiceResponse<?>) jsonConverter.handleResponse(request, response,
				serviceContext);
		if (webServerResponse == null) {
			return null;
		}
		if (!webServerResponse.isSuccess()) {
			throw new ServiceResponseException(webServerResponse.getStatus(), webServerResponse.getMessage());
		}

		// 由于 response.data 声明为 Object 类型，实际返回类型为 JsonElement ；
		Object responseData = webServerResponse.getData();
		if (responseData == null) {
			if (dataClazz.isPrimitive()) {
				// 针对基本类型，如果返回 null ，由于无法转换，所以报告异常；
				throw new IllegalStateException("Declared a primitive return type but received null response data!");
			}
			return null;
		}
		if (dataClazz.isAssignableFrom(responseData.getClass())) {
			return responseData;
		}
		if (dataClazz.isAssignableFrom(String.class)) {
			return responseData.toString();
		}
		if (DataTypeUtils.isPrimitiveType(dataClazz)) {
			// Object value = responseData.toValue(dataClazz);
			// 预期 responseData 实际也是基本类型，
			return DataTypeUtils.castTo(responseData, dataClazz);
		}
		if (responseData instanceof JsonElement) {
			return ((JsonElement) responseData).toValue(dataClazz);
		}
		throw new IllegalStateException("Cann't convert response data from type[" + responseData.getClass().getName()
				+ "] to required type[" + dataClazz.getName() + "]");
	}

}
